/*
 *  Copyright © OpenAtom Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.openatom.ubml.model.common.definition.cef.element;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.openatom.ubml.model.common.definition.cef.IGspCommonField;
import org.openatom.ubml.model.common.definition.cef.collection.GspAssociationKeyCollection;
import org.openatom.ubml.model.common.definition.cef.collection.GspFieldCollection;
import org.openatom.ubml.model.common.definition.cef.entity.GspCommonField;
import org.openatom.ubml.model.common.definition.cef.json.element.GspAssociationDeserializer;
import org.openatom.ubml.model.common.definition.cef.json.element.GspAssociationSerializer;

/**
 * The Definition Of Association
 *
 * @ClassName: Association
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
@JsonSerialize(using = GspAssociationSerializer.class)
@JsonDeserialize(using = GspAssociationDeserializer.class)
public class GspAssociation implements Cloneable {
    /**
     * 字段集合
     */
    protected GspFieldCollection refElementCollection = null;
    private String id;
    private String refModelId = "";
    private String refModelPkgName = "";
    private String refModelCode = "";
    private String refModelName = "";
    private String refObjectId = "";
    private String refObjectCode = "";
    private String refObjectName = "";
    private GspAssociationKeyCollection associationKeyCollection = null;
    private IGspCommonField belongElement = null;
    private String where = "";
    private String assSendMessage = "";
    private ForeignKeyConstraintType foreignKeyConstraintType = ForeignKeyConstraintType.Permit;
    private GspDeleteRuleType deleteRuleType = GspDeleteRuleType.Refuse;
    /**
     * 国际化项前缀
     */
    private String privateI18nResourceInfoPrefix;
    /**
     * 关联模型信息
     */
    private AssoModelInfo privateAssoModelInfo;

    /**
     * 创建关联关系
     */
    public GspAssociation() {
        setForeignKeyConstraintType(ForeignKeyConstraintType.Permit);
        setDeleteRuleType(GspDeleteRuleType.Refuse);
        setAssoModelInfo(new AssoModelInfo());
    }

    /**
     * 标识。
     */
    public final String getId() {
        return this.id;
    }

    public final void setId(String value) {
        this.id = value;
    }

    /**
     * 引用的数据模型ID
     */
    public final String getRefModelID() {
        return refModelId;
    }

    public final void setRefModelID(String value) {
        refModelId = value;
    }

    /**
     * 引用的数据模型包ID
     */
    public final String getRefModelPkgName() {
        return refModelPkgName;
    }

    public final void setRefModelPkgName(String value) {
        refModelPkgName = value;
    }

    /**
     * 引用的数据模型编号
     */
    public final String getRefModelCode() {
        return refModelCode;
    }

    public final void setRefModelCode(String value) {
        refModelCode = value;
    }

    /**
     * 引用的数据模型名称
     */
    public final String getRefModelName() {
        return refModelName;
    }

    public final void setRefModelName(String value) {
        refModelName = value;
    }

    /**
     * 引用的节点ID
     */
    public final String getRefObjectID() {
        return refObjectId;
    }

    public final void setRefObjectID(String value) {
        refObjectId = value;
    }

    /**
     * 引用的节点名称
     */
    public final String getRefObjectName() {
        return refObjectName;
    }

    public final void setRefObjectName(String value) {
        refObjectName = value;
    }

    /**
     * 引用的节点编号
     */
    public final String getRefObjectCode() {
        return refObjectCode;
    }

    public final void setRefObjectCode(String value) {
        refObjectCode = value;
    }

    /**
     * 隶属于的元素
     */
    public final IGspCommonField getBelongElement() {
        if (belongElement == null) {
            belongElement = new GspCommonField();
        }
        return belongElement;
    }

    public final void setBelongElement(IGspCommonField value) {
        if (belongElement != value) {
            belongElement = value;
            this.getRefElementCollection().setParentObject(belongElement.getBelongObject());
        }
    }

    public final GspAssociationKeyCollection getKeyCollection() {
        if (associationKeyCollection == null) {
            associationKeyCollection = createKeyCollection();
        }
        return associationKeyCollection;
    }

    /**
     * KeyCollection
     */
    public final void setKeyCollection(GspAssociationKeyCollection value) {
        associationKeyCollection = value;
    }

    /**
     * 创建关联外键集合
     *
     * @return
     */
    protected GspAssociationKeyCollection createKeyCollection() {
        return new GspAssociationKeyCollection();
    }

    /**
     * 创建字段集合
     *
     * @return
     */
    protected GspFieldCollection createElementCollection() {
        return new GspFieldCollection(null);
    }

    public final GspFieldCollection getRefElementCollection() {
        if (refElementCollection == null) {
            refElementCollection = new GspFieldCollection(getBelongElement().getBelongObject());
        }
        return refElementCollection;
    }

    /**
     * 引用的元素集合
     */
    public final void setRefElementCollection(GspFieldCollection value) {
        refElementCollection = value;
    }

    /**
     * 过滤条件
     */
    public final String getWhere() {
        return this.where;
    }

    public final void setWhere(String value) {
        this.where = value;
    }

    /**
     * 提示错误信息
     */
    public final String getAssSendMessage() {
        return this.assSendMessage;
    }

    public final void setAssSendMessage(String value) {
        this.assSendMessage = value;
    }

    /**
     * 外键约束类型
     */
    public final ForeignKeyConstraintType getForeignKeyConstraintType() {
        return this.foreignKeyConstraintType;
    }

    public final void setForeignKeyConstraintType(ForeignKeyConstraintType value) {
        this.foreignKeyConstraintType = value;
    }

    /**
     * 删除规则类型
     */
    public final GspDeleteRuleType getDeleteRuleType() {
        return this.deleteRuleType;
    }

    public final void setDeleteRuleType(GspDeleteRuleType value) {
        this.deleteRuleType = value;
    }

    /**
     * 联接方式
     */
    public final JoinMode getJoinMode() {
        JoinMode joinMode = JoinMode.InnerJoin;
        if (this.belongElement != null) {
            if (this.belongElement.getIsRequire()) {
                joinMode = JoinMode.InnerJoin;
            } else {
                joinMode = JoinMode.OuterJoin;
            }
        }
        return joinMode;
    }

    public final String getI18nResourceInfoPrefix() {
        return privateI18nResourceInfoPrefix;
    }

    public final void setI18nResourceInfoPrefix(String value) {
        privateI18nResourceInfoPrefix = value;
    }

    public final AssoModelInfo getAssoModelInfo() {
        return privateAssoModelInfo;
    }

    public final void setAssoModelInfo(AssoModelInfo value) {
        privateAssoModelInfo = value;
    }

    /**
     * 克隆
     *
     * @return
     */
    public final GspAssociation clone() {
        Object tempVar = null;
        try {
            tempVar = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        GspAssociation newAssociation = (GspAssociation)((tempVar instanceof GspAssociation) ? tempVar : null);
        newAssociation.id = this.id;
        newAssociation.refModelId = this.refModelId;
        newAssociation.refModelCode = this.refModelCode;
        newAssociation.refModelName = this.refModelName;
        newAssociation.belongElement = this.belongElement;
        newAssociation.where = this.where;
        newAssociation.assSendMessage = this.assSendMessage;
        newAssociation.foreignKeyConstraintType = this.foreignKeyConstraintType;
        newAssociation.deleteRuleType = this.deleteRuleType;
        Object tempVar2 = associationKeyCollection.clone();
        newAssociation.associationKeyCollection = (GspAssociationKeyCollection)((tempVar2 instanceof GspAssociationKeyCollection)
                ? tempVar2
                : null);
        GspFieldCollection tempVar3 = refElementCollection.clone(null, newAssociation);
        newAssociation.refElementCollection = (GspFieldCollection)((tempVar3 instanceof GspFieldCollection) ? tempVar3
                : null);
        return newAssociation;
    }

    /**
     * 克隆
     *
     * @param element
     * @return
     */
    public final GspAssociation clone(IGspCommonField element) {
        Object tempVar = clone();
        GspAssociation newObj = (GspAssociation)((tempVar instanceof GspAssociation) ? tempVar : null);
        newObj.belongElement = element;
        if (refElementCollection != null) {
            newObj.refElementCollection = refElementCollection.clone(element.getBelongObject(), newObj);
        }
        return newObj;
    }
}